
import ij.process.ImageProcessor;
import ij.text.TextPanel;
import java.awt.Rectangle;
import java.util.ArrayList;


/**
 *
 * @author Michalis Dobekidis
 */
public class featureExtractor
{

     public featureExtractor()
     {

     }
     
     TextPanel logPanel = new TextPanel();
     public ArrayList<ArrayList<int[]>> featureVector;
     /**
    * It performs sampling using a sliding window.
    * @param imageObject characterizes the image.
    * @param width characterizes the width of sample.
    * @param height characterizes the height of sample.
    * @param stepX characterizes the step to move towards xx' axis.
    * @param stepY characterizes the step to move towards yy' axis.
    * @param roi  the Area of interest in which we want the window to run. if ommited we use the whole image width and height
    **/
    public TextPanel slidingWindow(ImageProcessor imageObject , int width , int height , int stepX , int stepY,Rectangle roi,String custom)
        {
            int TOTAL = imageObject.getWidth()*imageObject.getHeight();
            int totalHeight =  roi.height!=0?roi.height:(imageObject.getHeight()-height);
            int totalWidth  =  roi.width!=0?roi.width:(imageObject.getWidth()-width);


           featureVector = new ArrayList<ArrayList<int[]>>();
           featureVector.add(new ArrayList<int[]>());
            //

           // logPanel = textLog.getTextPanel();
           // logPanel.append(out.toString());

           int i;
           int j;
           int internalCounter = 0;
           int externalCounter = 0;
            for(i = roi.x; i<=totalHeight; i+=(stepY))
            {

                for(j = roi.y; j<=totalWidth; j+=(stepX))
                {
                   //int iCounter = i;
                  // int jCounter = j;
                  // imageObject.get(i,j);
                    //this.saveFeatures(this.custom(imageObject.subImage(i, j ,width , height)),false);
                    //makes sure the arrayList has enough space. dynamically increases the arrayList. If you need to change this,
                    // use trimToSize() to make sure it doesn't take any more space than needed.
                   int[] temp = new int[height*width];
                   temp = getVector(i,j,imageObject,height,width,custom);

                   //featureVector.get(assosiation).ensureCapacity(temp.length+1);
                  // featureVector.get(assosiation).add(internalCounter,temp);
                  // featureVector.get(i).add(internalCounter,(double)imageObject.get(i,j));
                   
                   //Array of doubles.
                  //outputArray[i][j] = temp;
                   internalCounter++;
                }
               internalCounter = 0;
               externalCounter++;
               // int sample = makeDouble(featureVector.get(i).get(i),featureVector.get(i).size(),i).length;
               
                
               // featureVector.ensureCapacity(i+1);
                //featureVector.add(new ArrayList<int[]>());
            }

         
             return logPanel;
          // textLog.close();
           // IJ.log(finalString);
          /* This is here for debug, to see if we can retrieve arrays of doubles, from the ArrayList. It works. 
           for(int c=0;c<featureVector.get(0).get(0).length;c++)
           {
               double tempValue = (double)featureVector.get(0).get(0)[c];
              // serializer(doubleTemp[c].toString(),false);
                //IJ.log("\n"+"IN >>>>"+tempValue+"::"+c+"--");
           }
           */

        }
    
    
      /*
     * Calculates the elements of the vector, and retrives their pixels.
     *
     * @param external columns
     * @param internal rows
     * @param imp actual image object
     * @param height of the box
     * @param width of the box
     * @return an array of Doubles (pixels)
     */
    private int[] getVector(int external, int internal, ImageProcessor imp,int height,int width,String custom)
    {
        int[] outputArray = new int[width*height];
        int counter = 0;
        int ext=external;
        int inte=internal;
        String str = "";
        int mean=0;
        for(int i=ext;i<external+height;i++)
        {
            for(int j=inte;j<internal+width;j++)
            {
                outputArray[counter] = imp.getPixel(i, j);


             if(custom.equals("mean"))
             {
                 mean = (mean + outputArray[counter]);
             }
             if(custom.equals("log"))
             {
                 str = str + Integer.toString(outputArray[counter]) + ", ";
             }
                counter+=1;
            }
           // logPanel.append(str);
            
        } 
        
          mean = Math.round(mean/outputArray.length);
          //If we are running the "MeanProcessor_" plugIn
          //Reconstruction happens on the fly here.
          if(custom.equals("mean"))
          {
              for(int i=ext;i<=external+height;i++)
              {
                  for(int j=inte;j<=internal+width;j++)
                  {
                      imp.putPixel( i, j, mean);
                  }
                 
              }
          }
         else if(custom.equals("log")) // If we are running the "featureVector_" plugIn
         {
             logPanel.append(str);
         }
         
         
       // writeOutput(str);
        return outputArray;
    }

    
    
}
